﻿using BarManager.Core.ApplicationService.Interfaces;
using BarManager.Core.BusinessRules.Interfaces.Validator;
using BarManager.Core.DomainModel;
using BarManager.Core.DomainService;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;

namespace BarManager.Core.ApplicationService
{
    public abstract class BaseApplicationService<TEntity> : IApplicationService<TEntity> where TEntity : class
    {
        protected IRepository<TEntity> BaseRepository { get; private set; }
        protected IUnitOfWork UnitOfWork { get; private set; }
        protected IValidator<TEntity> Validator { get; private set; }

        public BaseApplicationService(IObjectContext context, IRepository<TEntity> repository,
            IValidator<TEntity> validator)
        {
            this.BaseRepository = repository;
            this.Validator = validator;
            this.UnitOfWork = context as IUnitOfWork;
        }

        public virtual TEntity Create()
        {
            return this.BaseRepository.Create();
        }

        public virtual TEntity Get(Expression<Func<TEntity, bool>> condition)
        {
            return this.BaseRepository.Get(condition);
        }

        public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> condition)
        {
            return this.BaseRepository.Find(condition);
        }

        public IEnumerable<TEntity> GetAll()
        {
            return this.BaseRepository.GetAll();
        }

        public virtual IEnumerable<string> Add(TEntity entity)
        {
            if (Validator.IsValid(entity, ValidatorType.Add))
            {
                this.BaseRepository.Add(entity);
                UnitOfWork.Commit();
            }
            return Validator.BrokenRules();
        }

        public virtual IEnumerable<string> Update(TEntity entity)
        {
            if (Validator.IsValid(entity, ValidatorType.Update))
            {
                this.BaseRepository.Update(entity);
                UnitOfWork.Commit();
            }
            return Validator.BrokenRules();
        }

        public virtual IEnumerable<string> Delete(TEntity entity)
        {
            if (Validator.IsValid(entity, ValidatorType.Delete))
            {
                this.BaseRepository.Delete(entity);
                UnitOfWork.Commit();
            }
            return Validator.BrokenRules();
        }             
    }
}
